package com.price.common.extend

import android.app.Activity
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.nfc.NdefMessage
import android.nfc.NdefRecord
import android.nfc.NfcAdapter
import android.nfc.Tag
import android.nfc.tech.MifareClassic
import android.nfc.tech.MifareUltralight
import android.nfc.tech.Ndef
import android.os.Build
import java.math.BigInteger
import java.nio.charset.Charset
import java.util.Locale

//RequiresPermission(Manifest.permission.NFC)
/**
<activity
android:name=".NFCActivity"
android:exported="true" >

<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>

<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>

<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>

<!--定义了android.nfc.action.TECH_DISCOVERED的具体NFC技术-->
<!--资源文件位于xml/nfc_tech_filter.xml中-->
<meta-data android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="@xml/nfc_tech_filter"/>

</activity>
 */

// null 设备无NFC功能
inline fun Context.isNFCEnabled(): Boolean? =
    NfcAdapter.getDefaultAdapter(this)?.isEnabled

inline fun Activity.enableNFC() {
    if (isNFCEnabled() == true) {
        val mPendingIntent = PendingIntent.getActivity(
            this, 0, Intent(this, this::class.java)
                .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), PendingIntent.FLAG_MUTABLE
        )
        val ndef = IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED)
        val tag = IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED)
        try {
            ndef.addDataType("*/*")
        } catch (e: Exception) {
            e.printStackTrace()
            toast("NFC initialization exception")
        }
        val mFilters = arrayOf(ndef, tag)
        val mTechLists = arrayOf(
            arrayOf(
                MifareClassic::class.java.name
            )
        )
        NfcAdapter.getDefaultAdapter(this)
            ?.enableForegroundDispatch(this, mPendingIntent, mFilters, mTechLists)
    }
}

inline fun Activity.disableNFC() {
    if (isNFCEnabled() == true) {
        NfcAdapter.getDefaultAdapter(this)
            ?.disableForegroundDispatch(this)
    }
}

inline fun Intent.getNfcPIN(): String? {
    val action = this.action
    if (NfcAdapter.ACTION_TAG_DISCOVERED == action || NfcAdapter.ACTION_TECH_DISCOVERED == action) {
        val tagId = this.getByteArrayExtra(NfcAdapter.EXTRA_ID)
        var tID = ""
        var tagIDLength = 10
        var strTemp = "0000000000"
        if (tagId!!.size > 4 && tagId.size <= 7) {
            tID = Right("00" + Integer.toHexString(tagId[6].toInt()).toString(), 2)
            tID += Right("00" + Integer.toHexString(tagId[5].toInt()).toString(), 2)
            tID += Right("00" + Integer.toHexString(tagId[4].toInt()).toString(), 2)
            tagIDLength = 17
            strTemp = "00000000000000000"
        }
        tID += (Right("00" + Integer.toHexString(tagId[3].toInt()).toString(), 2)
                + Right("00" + Integer.toHexString(tagId[2].toInt()).toString(), 2)
                + Right("00" + Integer.toHexString(tagId[1].toInt()).toString(), 2)
                + Right("00" + Integer.toHexString(tagId[0].toInt()).toString(), 2))
        val bi = BigInteger(tID, 16)
        return Right(strTemp + bi.toString(), tagIDLength)
    }
    return null
}

inline fun Right(text: String, length: Int): String {
    return text.substring(text.length - length, text.length)
}

fun Intent.getNfcTag(): Tag? {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        this.getParcelableExtra(NfcAdapter.EXTRA_TAG, Tag::class.java)
    } else {
        this.getParcelableExtra(NfcAdapter.EXTRA_TAG)
    }
}


fun Intent.readNdefRecodes(): ArrayList<String>? {
    val results= arrayListOf<String>()
    try {
    val ndefMessage= if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            this.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES, NdefMessage::class.java)
        } else {
            this.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES) as Array<NdefMessage>
        }
        if(ndefMessage!=null) {
            for (message in ndefMessage) {
                for(recode in message.records) {
                    results.add(String(recode.payload, Charset.forName("UTF-8")))
                }
            }
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return results

}
fun Intent.readNdefMessage(): Array<NdefMessage>? {
    return try {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            this.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES, NdefMessage::class.java)
        } else {
            this.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES) as Array<NdefMessage>
        }
    } catch (e: Exception) {
        e.printStackTrace()
        null
    }
}
fun NdefMessage.getResults():ArrayList<String>{
    val results= arrayListOf<String>()
    try {
        val recodes=this.records
        for(recode in recodes){
            if(recode!=null){
                results.add(String(recode.payload,Charset.forName("UTF-8")))
            }
        }
        return results
    }catch (e:Exception){
        e.printStackTrace()
    }
    return results
}

fun Tag.readTechPayloadMc() {
    val mc=MifareClassic.get(this)
    var bCount=0
    var bIndex=0

    try {
        mc.connect()
        val sectorCount=mc.sectorCount
        var index=0
        while(index<sectorCount){
            //尝试通过认证
            val auth=mc.authenticateSectorWithKeyA(index,MifareClassic.KEY_DEFAULT)
            if(auth){
                bCount=mc.getBlockCountInSector(index)
                bIndex=mc.sectorToBlock(index)
                var j=0
                while(j < bCount){
                    val data=mc.readBlock(bIndex)

                    val str= String(data, Charset.forName("UTF-8"))

                    bIndex++
                    j++
                }
            }
            index++
        }

    }catch (e:Exception){

    }
}

/**
 * 创建NDEF文本数据
 * @param text
 * @return
 */
fun createTextRecord(text: String): NdefRecord {
    val langBytes = Locale.CHINA.language.toByteArray(Charset.forName("US-ASCII"))
    val utfEncoding = Charset.forName("UTF-8")
    //将文本转换为UTF-8格式
    val textBytes = text.toByteArray(utfEncoding)
    //设置状态字节编码最高位数为0
    var utfBit = 0
    //定义状态字节
    val status = (utfBit + langBytes.size) as Char
    val data = ByteArray(1 + langBytes.size + textBytes.size)
    //设置第一个状态字节，先将状态码转换成字节
    data[0] = status as Byte
    //设置语言编码，使用数组拷贝方法，从0开始拷贝到data中，拷贝到data的1到langBytes.length的位置
    System.arraycopy(langBytes, 0, data, 1, langBytes.size)
    //设置文本字节，使用数组拷贝方法，从0开始拷贝到data中，拷贝到data的1 + langBytes.length
    //到textBytes.length的位置
    System.arraycopy(textBytes, 0, data, 1 + langBytes.size, textBytes.size)
    //通过字节传入NdefRecord对象
    //NdefRecord.RTD_TEXT：传入类型 读写
    return NdefRecord(
        NdefRecord.TNF_WELL_KNOWN,
        NdefRecord.RTD_TEXT, byteArrayOf(0), data
    )
}

/**
 * 写数据
 * @param ndefMessage 创建好的NDEF文本数据
 * @param tag 标签
 * @return
 */
fun Tag.writeTag(ndefMessage: NdefMessage): Boolean {
    try {
        val ndef = Ndef.get(this)
        ndef.connect()
        ndef.writeNdefMessage(ndefMessage)
        return true
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return false
}

fun Tag.writeTag(text: String): Boolean {
    try {
        val msg = createTextRecord(text)
        val ndefMessage = NdefMessage(arrayOf(msg))
        return writeTag(ndefMessage)
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return false
}
